package com.zhkj.txg.module.find.vm

import android.app.Application
import android.graphics.BitmapFactory
import androidx.lifecycle.MutableLiveData
import com.zhkj.lib.base.BaseViewModel
import com.zhkj.lib.base.UploadResponse
import com.zhkj.lib.http.*
import com.zhkj.txg.module.find.entity.*
import com.zhkj.txg.module.find.model.FindApi
import com.zhkj.txg.module.find.model.FindManager
import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
import java.net.URL

class FindViewModel(application: Application) : BaseViewModel(application) {
    private val findManager: FindManager = FindManager(FindApi::class.java)
    private val findListLiveData = MutableLiveData<HttpResponse<FindListResponse>>()
    val findArticleLiveData = MutableLiveData<HttpResponse<FindArticleResponse>>()
    val commentCommitLiveData = MutableLiveData<HttpResponse<BaseResponse>>()
    val findCommentLiveData = MutableLiveData<HttpResponse<FindCommentResponse>>()
    val likeLiveData = MutableLiveData<HttpResponse<BaseLikeResponse>>()
    val likeCommentLiveData = MutableLiveData<HttpResponse<BaseLikeResponse>>()
    val deleteCommentLiveData = MutableLiveData<HttpResponse<BaseLikeResponse>>()
    val productListLiveData = MutableLiveData<HttpResponse<AssociateProductResponse>>()
    val searchProductLiveData = MutableLiveData<HttpResponse<AssociateProductResponse>>()
    val publishArticleLiveData = MutableLiveData<HttpResponse<BaseResponse>>()

    var selectProduct: AssociateProductEntity? = null

    // 每页个数
    private val numb = 10

    // 当前页数
    private var page = 1

    // 搜索商品页数
    private var searchPage = 1

    fun findList(
        token: String,
        restart: Boolean = false
    ): MutableLiveData<HttpResponse<FindListResponse>> {
        val listener = object : ViewModelSubscribeListener<FindListResponse>(findListLiveData) {
            override fun onSuccess(resp: FindListResponse) {
                resp.data.hasMore = resp.data.list.size >= numb
                resp.data.isLoadMore = page > 1
                super.onSuccess(resp)
                page += 1
            }
        }
        if (restart) page = 1
        val findList = findManager.findList(token, page, numb, listener)
        dispose.add(findList)
        return findListLiveData
    }

    fun findArticleDetail(
        token: String,
        id: Int
    ): MutableLiveData<HttpResponse<FindArticleResponse>> {
        val listener =
            object : ViewModelSubscribeListener<FindArticleResponse>(findArticleLiveData) {
                override fun onSuccess(resp: FindArticleResponse) {
                    super.onSuccess(resp)
                    findArticleCommentList(token, id, true)
                }
            }
        val findDetail = findManager.findDetail(token, id, listener)
        dispose.add(findDetail)
        return findArticleLiveData
    }

    fun findArticleCommentList(token: String, id: Int, restart: Boolean = false) {
        val listener =
            object : ViewModelSubscribeListener<FindCommentResponse>(findCommentLiveData) {
                override fun onSuccess(resp: FindCommentResponse) {
                    resp.hasMore = resp.data.size >= numb
                    resp.isLoadMore = page > 1
                    super.onSuccess(resp)
                    page += 1
                }
            }
        if (restart) page = 1
        val commentList = findManager.findArticleCommentList(token, id, page, numb, listener)
        dispose.add(commentList)
    }

    fun commentCommit(
        token: String,
        id: Int,
        commentId: Int,
        content: String
    ) {
        val listener = ViewModelSubscribeListener(commentCommitLiveData)
        val commentCommit = findManager.commentCommit(token, id, commentId, content, listener)
        dispose.add(commentCommit)
    }

    fun likeFind(token: String, id: Int, commentId: Int, type: Int, uiIndex: Int) {
        val listener =
            object : ViewModelSubscribeListener<BaseLikeResponse>(
                if (type == 0) likeLiveData else likeCommentLiveData
            ) {
                override fun onSuccess(resp: BaseLikeResponse) {
                    resp.uiIndex = uiIndex
                    super.onSuccess(resp)
                }
            }
        val likeFind = findManager.likeFind(token, id, commentId, type, listener)
        dispose.add(likeFind)
    }

    fun deleteComment(token: String, id: Int, commentId: Int, uiIndex: Int) {
        val listener =
            object : ViewModelSubscribeListener<BaseLikeResponse>(deleteCommentLiveData) {
                override fun onSuccess(resp: BaseLikeResponse) {
                    resp.uiIndex = uiIndex
                    super.onSuccess(resp)
                }
            }
        val deleteComment = findManager.deleteComment(token, id, commentId, listener)
        dispose.add(deleteComment)
    }

    fun associateProductList(
        token: String,
        restart: Boolean = false
    ) {
        val listener =
            object : ViewModelSubscribeListener<AssociateProductResponse>(productListLiveData) {
                override fun onSuccess(resp: AssociateProductResponse) {
                    resp.hasMore = resp.data.size >= numb
                    resp.isLoadMore = page > 1
                    if (!resp.isLoadMore && resp.data.isNotEmpty()) {
                        resp.data.forEach { it.itemType = AssociateProductEntity.TYPE_PRODUCT }
                        resp.data.add(
                            0, AssociateProductEntity(0).apply { itemType = AssociateProductEntity.TYPE_NONE }
                        )
                    }
                    super.onSuccess(resp)
                    page += 1
                }
            }
        if (restart) page = 1
        val productList = findManager.associateProductList(token, page, numb, "", listener)
        dispose.add(productList)
    }

    fun searchAssociateProduct(
        token: String,
        searchKey: String,
        restart: Boolean = false
    ) {
        val listener =
            object : ViewModelSubscribeListener<AssociateProductResponse>(searchProductLiveData) {
                override fun onSuccess(resp: AssociateProductResponse) {
                    resp.hasMore = resp.data.size >= numb
                    resp.isLoadMore = searchPage > 1
                    super.onSuccess(resp)
                    searchPage += 1
                }
            }
        if (restart) searchPage = 1
        val productList =
            findManager.associateProductList(token, searchPage, numb, searchKey, listener)
        dispose.add(productList)
    }

    fun publishArticle(
        token: String,
        content: String,
        images: MutableList<FindPictureEntity>
    ) {
        uploadPicture(images, 0, token, content)
    }

    fun uploadPicture(
        images: MutableList<FindPictureEntity>, index: Int, token: String,
        content: String
    ) {
        if (index < images.size && !images[index].pictureFilePath.isNullOrBlank()) images[index].pictureFilePath?.let {
            val listener = object : SubscribeListener<UploadResponse> {
                override fun onStart() {
                    publishArticleLiveData.postValue(HttpResponse<BaseResponse>().apply {
                        status = HttpResponseStatus.Status.START
                    })
                }

                override fun onSuccess(resp: UploadResponse) {
                    images[index].uploadUrl = resp.data?.url
                    uploadPicture(images, index + 1, token, content)
                }

                override fun onFailure(throwable: Throwable) {
                    throwable.printStackTrace()
                    publishArticleLiveData.postValue(HttpResponse<BaseResponse>().apply {
                        status = HttpResponseStatus.Status.FAILURE
                        val error = ResponseSubscribeListener.handleThrowable(throwable)
                        exception = error
                    })
                }
            }
            val uploadPicture = findManager.uploadPicture(it, listener)
            dispose.add(uploadPicture)
        } else {
            val builder = StringBuilder()
            images.forEach { if (it.itemType == 1) builder.append(it.uploadUrl).append(",") }
            val imageStr = builder.deleteCharAt(builder.lastIndex).toString()
            val listener = ViewModelSubscribeListener(publishArticleLiveData)
            val publishArticle =
                findManager.publishArticle(
                    token,
                    content,
                    imageStr,
                    selectProduct?.goodsId ?: 0,
                    listener
                )
            dispose.add(publishArticle)
        }
    }

    private fun getPictureSize(resp: FindListResponse) {
        if (resp.data.list.isNotEmpty()) Observable.fromIterable(resp.data.list).map { entity ->
            entity.also {
                if (it.images.isNotEmpty()) {
                    URL(it.images).openConnection().getInputStream().use { `is` ->
                        val options = BitmapFactory.Options()
                        options.inJustDecodeBounds = true
                        BitmapFactory.decodeStream(`is`, null, options)
                        it.width = options.outWidth
                        it.height = options.outHeight
                    }
                }
            }
        }.toList().subscribeOn(Schedulers.io()).subscribe({
            resp.data.list = it
            findListLiveData.postValue(HttpResponse<FindListResponse>().apply {
                response = resp
                status = HttpResponseStatus.Status.SUCCESS
            })
            page += 1
        }, { it.printStackTrace() })
    }
}